<?php
namespace app\services\ai;

use app\services\ai\traits\HasHttpRequest;
use app\services\ai\traits\baidu\Voice;
use think\facade\Cache;

class Baidu implements AiInterface
{
    use HasHttpRequest, Voice;

    const API_AUTH_TOKEN_URI = 'https://aip.baidubce.com/';
    const API_AUTH_TOKEN = 'oauth/2.0/token';
    const API_SERVER_URI = 'http://vop.baidu.com/'; //语音识别
    const API_SERVER_API = 'server_api'; //语音识别
    const API_TEXT_2_AUDIO_URI = 'http://tsn.baidu.com/'; //语音合成
    const API_TEXT_2_AUDIO = 'text2audio'; //语音合成

    public $error = '';
    public $error_description = '';

    protected $apiKey;
    protected $secretKey;
    protected $apiName;
    protected $accessToken;
    protected $ci;

    public function __construct($config)
    {
        $this->apiKey = $config['api_key'] ;
        $this->secretKey = $config['secret_key'] ?? '';
        $this->accessToken = $this->getAccessToken();
    }

    /**
     * 获取不同接口的uri
     * @return string
     */
    public function getBaseUri()
    {
        switch ($this->apiName) {
            case self::API_TEXT_2_AUDIO:
                return self::API_TEXT_2_AUDIO_URI;
            case self::API_SERVER_API:
                return self::API_SERVER_URI;
        }
        return self::API_AUTH_TOKEN_URI;
    }

    /**
     * 取access token 30天时效
     * @return bool|mixed
     */
    public function getAccessToken()
    {
        $cacheName = $this->apiKey.'_token';

        $accessToken = Cache::get($cacheName);
        if ($accessToken) {
            return $accessToken;
        }

        $res = $this->post(self::API_AUTH_TOKEN, [
            'grant_type' => 'client_credentials',
            'client_id' => $this->apiKey,
            'client_secret' => $this->secretKey,
        ]);

        $accessToken = $res['access_token'] ?? false;
        if ($accessToken) {
            Cache::set($cacheName, $accessToken, 43200);
            return $accessToken;
        }
        $this->error = $res['error'] ?? '';
        $this->error_description = $res['error_description'] ?? '';
        return false;
    }

    /**
     * 调用不同API
     * @param $api_name
     * @param array $params
     * @param string $method
     * @return array|bool|string
     */
    public function call($api_name, $params = [], $method = self::POST)
    {
        $this->apiName = $api_name;
        if ($this->accessToken) {

            if ($method == self::POST) {
                $data = [
                    'form_params' => $params,
                ];
            } elseif ($method == self::JSON) {
                $method = self::POST;
                $data = [
                    'json' => $params,
                ];
            } else {
                $data = $params;
            }

            $res = $this->request($method, $api_name, $data);
            if ($res) {
                $this->error = $res['err_no'] ?? '';
                $this->error_description = $res['err_msg'] ?? '';
                return $res;
            }
        }
        return false;
    }

    /**
     * 为了兼容接口
     */
    public function sign($params)
    {
        // TODO: Implement sign() method.
    }

    public function parseOptions($params)
    {
        // TODO: Implement parseOptions() method.
    }
}
